// 实现这个项目的构建任务
const { src, dest, parallel, series, watch } = require('gulp');
const path = require('path');
const loadPlugins = require('gulp-load-plugins');
const del = require('del');
const browserSync = require('browser-sync').create();
// browserify babelify vinyl-source-stream
const browserify = require('browserify');
const babelify = require('babelify');
const source = require('vinyl-source-stream');


const root = 'src';
const resolve = (dir = '.', middle) => {
  return path.join(__dirname, middle || root, dir);
}
const plugins = loadPlugins();

const style_src = resolve('assets/styles/*.scss');
const script_src = resolve('assets/scripts/*.js');
const page_src = resolve('./*.html');
const image_src = resolve('assets/images/**');
const font_src = resolve('assets/fonts/**');
const extra_src = resolve('**', 'public');
const data = require('./data.config.js');


const clean = () => {
  return del(['dist', 'release']);
}

const _styles = () => {
  return src(style_src, { base: root })
    .pipe(plugins.sass({ outputStyle: 'expanded' }))
    .pipe(dest('dist'));
}

const _scripts = () => {

  // return src(script_src, { base: root })
  //     .pipe(plugins.babel({ presets: ['@babel/preset-env'] }))
  //     .pipe(plugins.concat('main.js'))// gulp-concat----合并文件
  //     // .pipe(plugins.rename('all.min.js')) // gulp-rename----重命名
  //     .pipe(plugins.uglify()) // gulp-uglify----压缩文件
  //     .pipe(dest('dist/assets/scripts/'));

  // http://egorsmirnov.me/2015/05/25/browserify-babelify-and-es6.html
  return browserify({ entries: './src/assets/scripts/main.js' })
    .transform(babelify, {
      presets: [
        '@babel/preset-env'
      ],
    })
    .bundle()
    .pipe(source('main.js'))
    .pipe(dest('dist/assets/scripts/'));
}

const _pages = () => {
  return src(page_src, { base: root })
    .pipe(plugins.swig({ data }))
    .pipe(dest('dist'));
}

const _images = () => {
  return src(image_src, { base: root })
    .pipe(plugins.imagemin())
    .pipe(dest('dist'));
}

const _fonts = () => {
  return src(font_src, { base: root })
    .pipe(plugins.imagemin())
    .pipe(dest('dist'));
}

const _extra = () => {
  return src(extra_src).pipe(dest('dist'));
}

const _core_compile = parallel(_styles, _scripts, _pages);

const _compile = parallel(_core_compile, _images, _fonts);

const serve = () => {
  watch('src/assets/scripts/*.js', _scripts);
  watch('src/*.html', _pages);
  watch('src/assets/styles/*.scss', _styles);

  watch([
    image_src,
    font_src,
    extra_src
  ], browserSync.reload);

  browserSync.init({
    files: ["dist/**"],
    // notify: false,
    port: 2080,
    server: {
      baseDir: ["dist", "src", "public"],
      routes: {
        "/node_modules": "node_modules"
      },
      middleware: (req, res, next) => {
        next();
      }
    }
  })
}

const _copy_fonts = () => {
  return src('dist/assets/fonts/**', { base: 'dist' }).pipe(dest('release'));
}

const _copy_images = () => {
  return src('dist/assets/images/**', { base: 'dist' }).pipe(dest('release'));
}

const _copy_public = () => {
  return src(extra_src).pipe(dest('release'));
}

const useref = () => {
  return src('dist/*.html', { base: 'dist' })
    .pipe(plugins.useref({ searchPath: ['dist', '.'] }))
    .pipe(plugins.if(/\.js$/, plugins.uglify()))
    .pipe(plugins.if(/\.css$/, plugins.cleanCss()))
    .pipe(plugins.if(/\.html$/, plugins.htmlmin({
      collapseWhitespace: true
    })))
    .pipe(dest('release'));
}


const compile = series(clean, _compile);

const build = series(clean, parallel(_compile, _extra));

const develop = series(clean, _compile, serve);

const release = parallel(_copy_fonts, _copy_images, _copy_public, useref);


module.exports = {
  _styles,
  _scripts,
  _images,
  _fonts,
  _pages,
  _extra,
  clean,
  release,
  compile,
  build,
  develop,
}
